package main

import (
	"strconv"
	"sync/atomic"
)

var num int64

func main() {
	num = 0
	ch := make(chan string)

	for i := 0; i < 10000; i++ {
		go add(ch, i)
	}

	for i := 0; i < 10000; i++ {
		<-ch
	}

	println(num)
}
func add(ch chan string, i int) {
	atomic.AddInt64(&num, 1) // atomic的所有操作都是原子性的
	ch <- ("add" + strconv.Itoa(i))
}

// 返回值是10000，和预期的一样，说明在并发场景下，atomic也可以保证原子性操作
// 它是通过 CPU 指令，也就是在硬件层次去实现的，性能较好，不需要像 mutex 那样记录很多状态（自旋、饥饿模式、正常模式、信号量）
// 还有加锁、解锁操作，实际测试atmoic的内存消耗比mutex要少、耗时也少。
// 测试示例：https://www.cnblogs.com/ExMan/p/12622096.html
